/*
 * DialogController.cpp
 *
 *  Created on: 5.1.2010
 *      Author: apoi
 */

#include <QList>
#include <QTimer>

#include "DialogController.h"
#include "BlogView.h"
#include "ErrorDialog.h"
#include "ProgressDialog.h"

DialogController::DialogController (BlogView *parent, bool cancellable) : 
    QObject(parent), iShowTaskProgress(false), cancellable(cancellable)
{
    iParent = parent;
    iErrorDialog = new ErrorDialog(parent);
    iProgressDialog = new ProgressDialog(parent, cancellable);

    connect(iErrorDialog, SIGNAL(accepted()), this, SLOT(ErrorAccepted()));
    connect(iErrorDialog, SIGNAL(rejected()), this, SLOT(ErrorAccepted()));

    connect(iProgressDialog, SIGNAL(canceled()), this, SLOT(ExitProgress()));

    iCommandMessages << tr("Preparing")
            << tr("Fetching main page")
            << tr("Fetching blog RSD")
            << tr("Fetching user's blogs")
            << tr("Fetching pages")
            << tr("Fetching posts")
            << tr("Fetching categories")
            << tr("Fetching tags")
            << tr("Fetching page statuses")
            << tr("Fetching post statuses")
            << tr("Fetching comment statuses")
            << tr("Fetching comments")
            << tr("Loading a page")
            << tr("Adding a new page")
            << tr("Editing a page")
            << tr("Deleting a page")
            << tr("Loading a comment")
            << tr("Adding a new comment")
            << tr("Editing a comment")
            << tr("Deleting a comment")
            << tr("Loading a post")
            << tr("Adding a new post")
            << tr("Editing a post")
            << tr("Deleting a post")
            << tr("Fetching Gravatar")
            << tr("Adding a new category")
            << tr("Uploading a file")
            << tr("Fetching blog statistics")
            << tr("")
            << tr("Fetching location")
            << tr("Fetching api key")
            << tr("Opening network session");
}

DialogController::~DialogController()
{

}
    
void DialogController::ShowTaskProgress()
{
    // start display progress bar
    iShowTaskProgress = true;

    if (!iCommandList.isEmpty()) {
        qDebug("WP::DialogController::ShowTaskProgress - Showing current task progress");

        // have active commands, show progress for currently executing task
        ShowProgressDialog();

    } else {
        qDebug("WP::DialogController::ShowTaskProgress - Showing upcoming task progress");

    }
}
    
void DialogController::HideTaskProgress ()
{
    // do not display progress bar in future
    iShowTaskProgress = false;

    HideProgressDialog();
}

void DialogController::ShowInfoNote (const QString &title, const QString &message)
{
    ShowErrorDialog(title, message);
}

void DialogController::ShowWarningNote(const QString &warning)
{
    ShowErrorDialog(tr("Warning"), warning);
}
    
void DialogController::ShowErrorNote (const QString &error)
{
    ShowErrorDialog(tr("Error occurred"), error);
}

void DialogController::TaskStarted (TWPNetworkEngineCommand command, bool foreground)
{
    Q_UNUSED(foreground);
    // qDebug("WP::DialogController::TaskStarted %d: %d", command, iCommandList.size());

    // check status
	if (iCommandList.isEmpty()) {
        qDebug("WP::DialogController: Busy");

        // idle -> busy
	    iParent->ActivateBusyIndicator();
	}

    // record
    iCommandList.append(command);

	// bring up progress dialog if needed:
    //  this task is a foreground task, or we are showing all tasks
    //  no progress or error dialog is already visible
    /* Disable implicit progress dialogs for now
    if ((foreground || iShowTaskProgress) && !(iProgressDialog->isVisible() || iErrorDialog->isVisible()))
        ShowProgressDialog();
    */
}

void DialogController::TaskFinished (TWPNetworkEngineCommand command)
{
    // pop
    iCommandList.removeOne(command);
    
    // qDebug("WP::DialogController::TaskFinished %d: %d", command, iCommandList.size());

    // update progress bar
    UpdateTaskStatus();
}

void DialogController::TaskFailed (TWPNetworkEngineCommand command, QString msg)
{
    // pop
    iCommandList.removeOne(command);
 
    // qDebug("WP::DialogController::TaskFailed %d: %d", command, iCommandList.size());
    
    UpdateTaskStatus();

    // display error, hiding task progress
    ShowErrorDialog(iCommandMessages.at(command), msg);
}

void DialogController::UpdateTaskStatus () {
    if (iCommandList.isEmpty()) {
        qDebug("WP::DialogController: Idle");

        // busy -> idle
	    iParent->DeactivateBusyIndicator();

        // close progress dialog once idle
        // use a small hysteresis delay to avoid flickering
        QTimer::singleShot(100, this, SLOT(UpdateTaskIdle()));

    }
}

void DialogController::UpdateTaskIdle ()
{
    if (iCommandList.isEmpty()) {
        // progress is done
        HideProgressDialog();
        
        // unset temporal task progress once idle
        iShowTaskProgress = false;
    }
}
    
void DialogController::ExitProgress()
{
    /* In some rare cases the Cancel signal (originating from an UI event)
     * gets emitted so that it is received after the TaskFinished signal
     * emitted from who-knows-where. If list is empty ignore this cancel. 
     */
    if(iCommandList.isEmpty()) {
        UpdateTaskStatus();
        return;
    }
    
    if (cancellable) {
        // cancel the most recent task, as displayed in progress dialog
        TWPNetworkEngineCommand command = iCommandList.takeFirst();
        
        // actively cancel it
        emit TaskCancelled(command);

        // update our state
        UpdateTaskStatus();

    } else {
        iParent->close();
    }
}

void DialogController::ErrorAccepted()
{
    // XXX: already hidden
    // iError->hide();

    /* Disable implicit progress dialogs
    if (!iCommandList.isEmpty() && iShowTaskProgress)
        // continue with progress
        ShowProgressDialog();

    else
        */
        // done
        HideProgressDialog();
}

void DialogController::ShowErrorDialog (const QString &title, const QString &message)
{
    HideProgressDialog();

    iErrorDialog->ShowError(title, message);
}
    
void DialogController::HideErrorDialog ()
{
    iErrorDialog->close();
}

void DialogController::ShowProgressDialog ()
{
    HideErrorDialog();

    // show task name
    iProgressDialog->ShowTaskProgress(iCommandMessages.at(iCommandList.first()) + "...");
}

void DialogController::HideProgressDialog ()
{
    iProgressDialog->close();
}

